home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
byte0887.arc
/
LANE.ARC
/
PREDS80.ARI
< prev
next >
Wrap
Text File
|
1987-05-05
|
6KB
|
234 lines
% Subject: PREDS80.ARI - from A. Lane: "Simulating an 8085 with Prolog"
% bit_xor(A,B,C) :: C is exclusive-or of A and B
%
bit_xor(0,0,0) :- !.
bit_xor(0,1,1) :- !.
bit_xor(1,0,1) :- !.
bit_xor(1,1,0) :- !.
bit_xor(A,B,X) :-
AA0 is A // 2, A0 is A mod 2,
BB0 is B // 2, B0 is B mod 2,
bit_xor(AA0,BB0,XX0),
bit_xor(A0,B0,X0),
X is 2 * XX0 + X0.
% adjust_flags( In, Out, flags(Z,S,P,CY,AC)) :: In --> Out and flags checked.
%
adjust_flags(A,In, Out, flags(Z,S,P,CY,AC)) :-
check_carry( In, Out, CY ),
check_zero(Out,Z),
check_parity(Out,P),
check_aux_carry(A,Out,AC),
check_sign(Out,S).
% carry_on :: PC <-- PC + 2.
%
carry_on :-
retract(state(Regs,PC,SP,Flags)),
NewPC is PC + 2,
asserta(state(Regs,NewPC,SP,Flags)).
% check_zero(A,B) :: A == 0 --> B == 1, else B == 0.
%
check_zero(0,1) :- !.
check_zero(_,0).
% check_parity(X,Y) :: Y reflects odd parity of number of bits in X.
check_parity(X,Y) :- par(X,T), Y is T mod 2, !.
par(0,0) :- !.
par(1,1) :- !.
par(N,P) :- J is N mod 2,
K is N // 2,
par(K,P1),
P is J + P1.
check_sign(X,1) :- X > 127, !.
check_sign(_,0).
check_carry(In,Out,1) :- In > 255, Out is In - 255, !.
check_carry(In,Out,1) :- In < 0, Out is In + 255, !.
check_carry(In, In,0).
check_aux_carry(OldAccum, NewAccum, 1) :-
OldAccum /\ 24 =:= 8, % old bit 3 on and old bit 4 off
NewAccum /\ 24 =:= 16,!. % new bit 4 on and new bit 3 off
% (=:= evaluates both sides and tests for equality)
check_aux_carry(_,_,0) :- !.
zero_flag_is_set :-
state(_,_,_,flags(1,_,_,_,_)), !.
sign_flag_is_set :-
state(_,_,_,flags(_,1,_,_,_)), !.
parity_flag_is_set :-
state(_,_,_,flags(_,_,1,_,_)), !.
carry_flag_is_set :-
state(_,_,_,flags(_,_,_,1,_)), !.
aux_carry_flag_is_set :-
state(_,_,_,flags(_,_,_,_,1)), !.
% reset (N) :: store PC on stack, PC <-- 8 * N.
%
reset(N) :-
retract(state(Registers,PC,SP,Flags)),
decompose(PC,PCH,PCL),
Hi is SP - 1,
put_mem(Hi,PCH),
NewSP is SP - 2,
put_mem(NewSP,PCL),
NewPC is 8 * N,
asserta(state(Registers,NewPC,NewSP,Flags)).
% return :: pop PC off stack, adjust SP.
%
return :-
retract(state(Registers,_,SP,Flags)),
get_mem(SP,PCL),
Hi is SP + 1,
get_mem(Hi,PCH),
PC is 256 * PCH + PCL,
NewSP is SP + 2,
asserta(state(Registers,PC,NewSP,Flags)).
jump :-
retract(state(Registers,PC,SP,Flags)),
get_mem(PC,PCL),
Hi is PC + 1,
get_mem(Hi,PCH),
NewPC is 256 * PCH + PCL,
asserta(state(Registers,NewPC,SP,Flags)).
call :-
retract(state(Registers,PC,SP,Flags)),
PCN is PC + 2, % here? or on return?
PCH is PCN // 256,
PCL is PCN mod 256,
SP1 is SP - 1,
SP2 is SP - 2,
put_mem(SP1,PCH),
put_mem(SP2,PCL),
get_mem(PC,NPCL),
Hi is PC + 1,
get_mem(Hi,NPCH),
NewPC is 256 * NPCH + NPCL,
asserta(state(Registers,NewPC,SP2,Flags)).
% put_mem( H, L, Data) :: store Data in Address <-- 256 * H + L.
%
put_mem( Hi, Lo, NewData ) :-
Address is 256 * Hi + Lo,
put_mem(Address, NewData).
% put_mem( H, L, Data) :: store Data in Address.
%
put_mem(Address,NewData) :-
retract(memory(Address,_)),
asserta(memory(Address,NewData)).
% get_mem( H, L, Data) :: fetch Data in Address <-- 256 * H + L.
%
get_mem(Hi, Lo, Data ) :-
Address is 256 * Hi + Lo,
get_mem(Address,Data).
% get_mem( Address, Data) :: fetch Data in Address.
%
get_mem(Address, Data) :-
memory(Address,Data).
% decompose(Address, Hibyte, Lobyte) :: Address <-- 256 * Hibyte + Lobyte
% (o,i,i)
%
decompose(Address, Hibyte, Lobyte) :- % (o,i,i)
var(Address), % if Address is uninstantiated
Address is 256 * Hibyte + Lobyte.
% decompose(Address, Hibyte, Lobyte) :: Address --> Hibyte ; Lobyte
% (i,o,o)
%
decompose(Address, Hibyte, Lobyte) :- % (i,o,o)
F is Address / 256,
H is integer(F),
Hibyte is H /\ 255,
G is Address - 256 * H,
Lobyte is integer(G).
put_address(Lo) :- % write an address in hex
decompose(Lo,LoH,LoL),
dec_hex_byte(LoH,LHH),
dec_hex_byte(LoL,LLH),
write(LHH),write(LLH),write(' : '),!.
% Decimal-to-hex and Hex-to-decimal Conversions.
%
dec_hex_byte( Dec, Hex ) :- % (i,o)
var(Hex),!,
Dec < 256,
Hi is Dec >> 4,
Lo is Dec /\ 15,
d_h(Hi,H),
d_h(Lo,L),
list_text([H,L],Hex).
dec_hex_byte( Dec, Hex ) :- % (o,i)
list_text([H,L],Hex),
d_h(Hi,H),
d_h(Lo,L),
Dec is 16 * Hi + Lo,!.
d_h( In, Out ) :- % (i,o)
In < 10,
Out is In + 48.
d_h( In, Out ) :- % (i,o)
Out is In + 55.
d_h( Out, In ) :- % (o,i)
In < 65,
Out is In - 48.
d_h( Out, In ) :- % (o,i)
In < 71,
Out is In - 55.
min(I1,I1,I2) :- I1 =< I2, !.
min(I2,I1,I2) :- I2 < I1.
for(X,X,X) :- !.
for(X,Y,X).
for(X,Y,Z) :- X1 is X + 1, for(X1,Y,Z).
append([H|T], L, [H|R]) :- !, append(T, L, R).
append([], L, L).
valid_adr(H,L) :- top_of_memory(TOM), TOM >= (256 * H + L).
reg(a,1). reg(b,2). reg(c,3). reg(d,4).
reg(e,5). reg(h,6). reg(l,7).
fl(z,1). fl(s,2). fl(p,3). fl(cy,4). fl(ac,5).
%
% end: PREDS80.ARI